<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Validator;
use App\Helpers\ValidatorResponse;
use App\Helpers\SuccessResponse;
use App\Http\Model\Qr;
use Illuminate\Support\Facades\DB;
use App\Http\Constant;
use Endroid\QrCode\QrCode;
use Endroid\QrCode\ErrorCorrectionLevel;
use Endroid\QrCode\LabelAlignment;
class QrController extends Controller{

	public function __construct(){

	}

	public function get(){
		$qr_data = ['expire_time' => time() + env('QR_VALIDATE_TIME', 10)];
		$qr_id = md5(json_encode($qr_data));
		$qrcode_path = $this->_getQrCodeSavePath($qr_id);
		
		try{
			$qrCode = new QrCode(base64_encode(json_encode(array_merge($qr_data, ['qr_id' => $qr_id]))));
			$qrCode->setWriterByName('png')
				->setMargin(10)
				->setEncoding('UTF-8')
				->setErrorCorrectionLevel(ErrorCorrectionLevel::HIGH)
				->setForegroundColor(['r' => 0, 'g' => 0, 'b' => 0])
				->setBackgroundColor(['r' => 255, 'g' => 255, 'b' => 255])
				// ->setLabel('Scan the code', 16, false, LabelAlignment::CENTER)
				->setLogoPath(WEB_ROOT.'/resources/images/logo.png')
				->setLogoWidth(60)
				->setValidateResult(false)
				->writeFile($qrcode_path);
			$qr_model = new Qr();
			$qr_model->qr_id = $qr_id;
			$qr_model->expire_time = $qr_data['expire_time'];
			$qr_model->create_ipv4 = $this->ip();
			$qr_model->save();
		}catch(\Exception $e){
			return SuccessResponse::handler('['.$e->getCode().'] '.$e->getMessage());
		}

		$rtn = array_merge($qr_data, ['qr_id' => $qr_id, 'qr_url' => $this->_getQrUrlFromSavePath($qrcode_path)]);
		return SuccessResponse::handler($rtn);
	}

	public function ask(Request $request){
		$validator = Validator::make($request->all(), [
			'qr_id' => 'required|string|max:32|min:32',
		]);
		if($validator->fails()){
			return ValidatorResponse::handler($validator->errors());
		}else{
			$qr_model = new Qr();
			try{
				$qr = $qr_model->where('qr_id', '=', $request->input('qr_id'))->get()->toArray();
			}catch(\Exception $e){
				return SuccessResponse::handler('['.$e->getCode().'] '.$e->getMessage());
			}
			if(0 == count($qr)){
				return SuccessResponse::handler('['.Constant::EC_NO_QR_MATCHED.'] No qr [qr_id='.$request->input('qr_id').'] found.');
			}else{
				if(0 == strlen($qr[0]['jwt_token'])){
					return SuccessResponse::handler('['.Constant::EC_QR_NO_LOGINED.'] Qr [qr_id='.$request->input('qr_id').'] no logined.');
				}
				if(time() > intval($qr[0]['expire_time'])){
					return SuccessResponse::handler('['.Constant::EC_QR_EXPIRED.'] Qr [qr_id='.$request->input('qr_id').'] expired at '.date('Y-m-d H:i:s', $qr[0]['expire_time']).'.');
				}

				$rtn = [
					'jwt_token' => $qr[0]['jwt_token'],
					'user' => json_decode($qr[0]['user'], true),
					'user_id' => $qr[0]['user_id'],
				];
				return SuccessResponse::handler($rtn);
			}
		}
	}

	public function qrLogin(Request $request){
		$validator = Validator::make($request->all(), [
			'qr_id' => 'required|string|max:32|min:32',
			'jwt_token' => 'required|string',
			// 'user_id' => 'required|integer|min:1',
		]);
		if($validator->fails()){
			return ValidatorResponse::handler($validator->errors());
		}else{
			$qr_model = new Qr();
			try{
				$qr = $qr_model->where('qr_id', '=', $request->input('qr_id'))->get()->toArray();
			}catch(\Exception $e){
				return SuccessResponse::handler('['.$e->getCode().'] '.$e->getMessage());
			}
			if(0 == count($qr)){
				return SuccessResponse::handler('['.Constant::EC_NO_QR_MATCHED.'] No qr [qr_id='.$request->input('qr_id').'] found.');
			}else{
				if(time() > intval($qr[0]['expire_time'])){
					return SuccessResponse::handler('['.Constant::EC_QR_EXPIRED.'] Qr [qr_id='.$request->input('qr_id').'] expired at '.date('Y-m-d H:i:s', $qr[0]['expire_time']).'.');
				}
				$qr_data = [
					'jwt_token' => $request->input('jwt_token'),
					'update_ipv4' => $this->ip(),
					'user_id' => $request->input('user_id'),
				];
				$qr_model = new Qr();
				try{
					$qr_model->where('id', '=', $qr[0]['id'])->update($qr_data);
				}catch(\Exception $e){
					return SuccessResponse::handler('['.$e->getCode().'] '.$e->getMessage());
				}
				$rtn = array_merge($qr_data, [
					'id' => $qr[0]['id'],
				]);
				return SuccessResponse::handler($rtn);
			}
		}
	}

	/**
	 * 从本机路径获取网络请求路径
	 * @param  string $save_path local path
	 * @return string url
	 */
	private function _getQrUrlFromSavePath($save_path){
		return str_replace(implode('/', [WEB_ROOT, 'public']), '', $save_path);
	}

	/**
	 * get qr save path & mkdir
	 * @param  [type] $qr_id [description]
	 * @return [type]        [description]
	 */
	private function _getQrCodeSavePath($qr_id){
		$path = implode('/', [WEB_ROOT, 'public', 'qr-code', date('Y-m-d'), date('H'), date('i'), 'qrcode-'.$qr_id.'.png']);
		$this->_mkdir(dirname($path));
		return $path;
	}

	private function _mkdir($dir){
	    if(!is_dir($dir)){
	        if(!$this->_mkdir(dirname($dir))){
	            return false;
	        }
	        if(!mkdir($dir,0777)){
	            return false;
	        }
	    }
	    return true;
	}

	private function ip() {
		if (@$_SERVER["HTTP_X_FORWARDED_FOR"])  
			$ip = $_SERVER["HTTP_X_FORWARDED_FOR"];  
		else if (@$_SERVER["HTTP_CLIENT_IP"])  
			$ip = $_SERVER["HTTP_CLIENT_IP"];  
		else if (@$_SERVER["REMOTE_ADDR"])  
			$ip = $_SERVER["REMOTE_ADDR"];  
		else if (@getenv("HTTP_X_FORWARDED_FOR"))  
			$ip = getenv("HTTP_X_FORWARDED_FOR");  
		else if (@getenv("HTTP_CLIENT_IP"))  
			$ip = getenv("HTTP_CLIENT_IP");  
		else if (@getenv("REMOTE_ADDR"))  
			$ip = getenv("REMOTE_ADDR");  
		else  
			$ip = "Unknown";  
		return $ip; 
	}
}